<?php
/**
 * MinimizeCSS , version 2.0
 * Copyright (c) 2008 Radovan Kepák (www.kepak.eu)
 * 
 * $rev$
 * 
 * MinimizeCSS is freely distributable under the terms of an MIT-style license.
 * For details, see the MinimizeCSS web site: http://go.itcrowd.cz/?minimizecss
 **/

/**
 * Class for stylesheet compression
 * @usage
 * 	Direct:
 * 	$compresed_css_content = CSSMin::minify($uncompresed_css_content);
 * 
 * 	Object
 * 	$compresor = new CSSMin($uncompresed_css_content);
 * 	$compresed_css_content = $compresor->min();
 * 	$new_size_percentage = $compresor->size();
 */

class CSSMin
{
    /**
     * Public static function
     * @param	$s	<string>	Input uncompressed string
     * @return		<string>	Compresed string
     */
    public static function minify($s)
    {
        $me = new self($s);
        return $me->min();
    }

    /**
     * Constructor
     * @param	$s	<string>	Input uncompressed string
     */
    public function __construct($s)
    {
        $this->_input = $s;
        $this->_tags = explode(',',
            'html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td');
        $this->_tags_before = array('}', ';');
        $this->_tags_css = array('.', '#');
    }

    /**
     * Public function min, to minify
     */
    public function min()
    {
        //Start the clock, the script is running
        $time = microtime(true);

        //Create input
        $this->_create_cache();

        //Now in right order create the output
        $this->_strip_comment();
        $this->_to_one_line();
        $this->_cut_white_space();
        $this->_clean_css();
        $this->_cut_tags_space();

        //Create output
        $this->_create_output();

        //Final time that conversion takes
        $this->_time = microtime(true) - $time;
        $this->_size = intval((strlen($this->_output) / strlen($this->_input))*100).'%';

        return $this->_output;
    }

    /**
     * Public function fetching ratio if is set, else return null
     */
    public function size()
    {
        if ($this->_size != false) {
            return $this->_size;
        }

        return false;
    }

    /**
     * Public function fetching number of seconds if is set, else return null
     */
    public function time()
    {
        if ($this->_time != false) {
            return $this->_time;
        }
    }

    /**
     * Protected function , striping any comment
     */
    protected function _strip_comment()
    {
        $this->_cache = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $this->_cache);
    }

    /**
     * Protected function , striping any enter, tab
     */
    protected function _to_one_line()
    {
        $this->_cache = str_replace(array("\r", "\n", "\t"), '', $this->_cache);
    }

    /**
     * Protected function , remove spaces and tags where they not supose to be
     */
    protected function _clean_css()
    {
        $this->_cache = str_replace(array(' {', '{ ', ' }', '} ', ': ', '; ', ', ', ' ,',
            ';;', ';}', ' > ', ' :'), array('{', '{', '}', '}', ':', ';', ',', ',', ';', '}',
            '>', ':'), $this->_cache);
    }

    /**
     * Protected function , replacing two and more spaces to one only
     */
    protected function _cut_white_space()
    {
        $this->_cache = preg_replace('/ [ ]+/i', ' ', $this->_cache);
    }

    /**
     * Protected function, cleaning spaces before HTML tags
     */
    public function _cut_tags_space()
    {
        $from = array();
        $for = array();

        foreach ($this->_tags as $t) {
            foreach ($this->_tags_before as $b) {
                foreach ($this->_tags_css as $c) {
                    $from[] = $b . $t . ' ' . $c;
                    $for[] = $b . $t . $c;
                }
            }
        }

        $this->_cache = str_replace($from, $for, $this->_cache);
    }

    /**
     * Protected function Input to Cache
     */
    protected function _create_cache()
    {
        $this->_cache = $this->_input;
    }

    /**
     * Protected function Cache to Output
     */
    protected function _create_output()
    {
        $this->_output = $this->_cache;
    }

    /**
     * Private vars
     */
    private $_tags = false;
    private $_tags_before = false;
    private $_tags_css = false;

    private $_cache = false;
    private $_input = false;
    private $_output = false;
    private $_size = false;
    private $_time = false;

}
?>